package com.zzt.zt_cropimageview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;

import java.io.File;
import java.lang.ref.SoftReference;

/**
 * @author: zeting
 * @date: 2022/11/23
 * 物料合成
 */
public class TempImageViewV1 extends androidx.appcompat.widget.AppCompatImageView {
    private static final String TAG = "TempImageView";

    private int mFocusWidth = 360;         //图片最小框的宽度
    private int mFocusHeight = 360;        //图片最小框的高度

    private RectF mFocusRect = new RectF(); // 添加一个最终缩放焦点位置

    private static final float MAX_SCALE = 4.0f;  //最大缩放比，图片缩放后的大小与中间选中区域的比值
    private static final int NONE = 0;   // 初始化
    private static final int DRAG = 1;   // 拖拽
    private static final int ZOOM = 2;   // 缩放
    private static final int ROTATE = 3; // 旋转
    private static final int ZOOM_OR_ROTATE = 4;  // 缩放或旋转

    private static final int SAVE_SUCCESS = 1001;  // 缩放或旋转
    private static final int SAVE_ERROR = 1002;  // 缩放或旋转

    private int mImageWidth;
    private int mImageHeight;
    private int mRotatedImageWidth;
    private int mRotatedImageHeight;
    private Matrix matrix = new Matrix();      //图片变换的matrix
    private Matrix savedMatrix = new Matrix(); //开始变幻的时候，图片的matrix
    private PointF pA = new PointF();          //第一个手指按下点的坐标
    private PointF pB = new PointF();          //第二个手指按下点的坐标
    private PointF midPoint = new PointF();    //两个手指的中间点
    private PointF mFocusMidPoint = new PointF();  //中间View的中间点
    private int mode = NONE;            //初始的模式
    private double rotation = 0;        //手指旋转的角度，不是90的整数倍，可能为任意值，需要转换成level
    private float oldDist = 1;          //双指第一次的距离
    private float mMaxScale = MAX_SCALE;//程序根据不同图片的大小，动态得到的最大缩放比
    private boolean isInited = false;   //是否经过了 onSizeChanged 初始化
    private boolean mSaving = false;    //是否正在保存
    private InnerHandler mHandler = new InnerHandler();
    // 绘制上面模板图片
    private Bitmap topBitmap;
    // 图片位置
    private Rect bgRect;
    // 图片显示位置
    private RectF bgRectF;
    private TempTextMessageObj messageObj;
    private Bitmap flagBim;//国旗
    // 文字画笔
    private TextPaint textPaint;
    // 背景圆角画笔
    private Paint tBgPaint;
    private RectF topRoundRect;// 上面框
    // 国旗画笔
    private Paint flagPaint;
    private RectF bottomRoundRect;// 下面框
    private RectF flagRectF;// 国旗框
    private Rect flagRectSrc;// 国旗框
    private Path mCropTempPath = new Path();// 扣洞路径
    private int cropMidColor;// 扣洞后的中间颜色
    // 扣洞的
    private Paint mCropPath;
    // 扣洞混合规则
    private Xfermode xModeSrc = new PorterDuffXfermode(PorterDuff.Mode.SRC);
    // 重新设置视图高
    private int height;

    public TempImageViewV1(Context context) {
        this(context, null);
    }

    public TempImageViewV1(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TempImageViewV1(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        //只允许图片为当前的缩放模式
        setScaleType(ScaleType.MATRIX);

        topBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.material_temp_bg_1);

        cropMidColor = ContextCompat.getColor(getContext(), R.color.color_3d4149_or_0f131b);

        // 图片展示区域
        bgRect = new Rect();
        // 显示画布区域
        bgRectF = new RectF();

        // 设置文本画笔
        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        // 设置框
        tBgPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        tBgPaint.setColor(Color.parseColor("#00783C"));
        tBgPaint.setStrokeWidth(2);
        tBgPaint.setStyle(Paint.Style.STROKE);

        // 国旗画笔
        flagPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);

        topRoundRect = new RectF();
        bottomRoundRect = new RectF();
        flagRectSrc = new Rect();
        flagRectF = new RectF();
        // 扣洞用的
        mCropPath = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    }

    public void setMessageObj(TempTextMessageObj messageObj) {
        this.messageObj = messageObj;
//        /**********************测试数据**********************/
//        String flagUrl = "http://test-cdn.daily-fx.net/treasure/images/profile/019bd25a805941ff85675e5e01bb1887_1669276913248.jpg";
//        Glide.with(getContext()).asBitmap().load(flagUrl).addListener(new RequestListener<Bitmap>() {
//            @Override
//            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
//                Log.d(TAG, "获取图片 失败：" + e);
//                e.printStackTrace();
//                return false;
//            }
//
//            @Override
//            public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
//                flagBim = resource;
//                Log.d(TAG, "获取图片成功：");
//                return false;
//            }
//        }).preload();
//        /**********************测试数据**********************/
        initImage();
    }

    /**
     * 设置顶部的模板图片
     */
    public void setTempTopBitmap(Bitmap bm) {
        this.topBitmap = bm;
        initImage();
    }


    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        initImage();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        initImage();
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        initImage();
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        initImage();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        isInited = true;
        initImage();
    }

    /**
     * 初始化图片和焦点框
     */
    private void initImage() {
        Drawable d = getDrawable();
        if (!isInited || d == null) return;
        mode = NONE;
        matrix = getImageMatrix();
        mImageWidth = mRotatedImageWidth = d.getIntrinsicWidth();
        mImageHeight = mRotatedImageHeight = d.getIntrinsicHeight();
        //计算出焦点框的中点的坐标和上、下、左、右边的x或y的值
        int viewWidth = getWidth();
        int viewHeight = getHeight();

        // 计算背景
        bgRect = new Rect(0, 0, topBitmap.getWidth(), topBitmap.getHeight());
        Log.w(TAG, "图片宽高：" + bgRect);
        Log.w(TAG, "视图宽高 W：" + viewWidth + " H:" + viewHeight);

        // 高的比例
        float hPro = NumberUtil.divide(topBitmap.getHeight(), viewHeight);
        float wPro = NumberUtil.divide(topBitmap.getWidth(), viewWidth);

        Log.i(TAG, "视图宽高比例 W：" + wPro + " H:" + hPro);

        if (wPro >= hPro) {
            float drawH = NumberUtil.divide(topBitmap.getHeight(), wPro);
            float hTop = (viewHeight - drawH) * 0.5F;
            bgRectF = new RectF(0, hTop, viewWidth, (float) (drawH + hTop));
        } else {
            float drawW = NumberUtil.divide(topBitmap.getWidth(), hPro);
            float hLeft = (viewWidth - drawW) * 0.5F;
            bgRectF = new RectF(hLeft, 0, (float) (drawW + hLeft), viewHeight);
        }
        Log.i(TAG, "绘制的目标视图宽高 ：" + bgRectF);

        // 设置最终焦点位置
        mFocusRect.left = 0.1F * (bgRectF.right - bgRectF.left) + bgRectF.left;
        mFocusRect.right = 0.35F * (bgRectF.right - bgRectF.left) + bgRectF.left;
        mFocusRect.top = 0.48f * (bgRectF.bottom - bgRectF.top) + bgRectF.top;
        mFocusRect.bottom = 0.85f * (bgRectF.bottom - bgRectF.top) + bgRectF.top;

        // 计算显示视图中心点
        mFocusMidPoint = new PointF(mFocusRect.centerX(), mFocusRect.centerY());

        //适配焦点框的缩放比例（图片的最小边不小于焦点框的最小边）
        float fitFocusScale = getScale(mImageWidth, mImageHeight, mFocusWidth, mFocusHeight, true);
        mMaxScale = fitFocusScale * MAX_SCALE;
        //适配显示图片的ImageView的缩放比例（图片至少有一边是铺满屏幕的显示的情形）
        float fitViewScale = getScale(mImageWidth, mImageHeight, mFocusRect.width(), mFocusRect.height(), false);
        //确定最终的缩放比例,在适配焦点框的前提下适配显示图片的ImageView，
        //方案：首先满足适配焦点框，如果还能适配显示图片的ImageView，则适配它，即取缩放比例的最大值。
        //采取这种方案的原因：有可能图片很长或者很高，适配了ImageView的时候可能会宽/高已经小于焦点框的宽/高
        float scale = fitViewScale > fitFocusScale ? fitViewScale : fitFocusScale;
        //图像中点为中心进行缩放
        matrix.setScale(scale, scale, mFocusRect.centerX(), mFocusRect.centerY());
        float[] mImageMatrixValues = new float[9];
        matrix.getValues(mImageMatrixValues); //获取缩放后的mImageMatrix的值
        float transX = mFocusMidPoint.x - (mImageMatrixValues[2] + mImageWidth * mImageMatrixValues[0] / 2);  //X轴方向的位移
        float transY = mFocusMidPoint.y - (mImageMatrixValues[5] + mImageHeight * mImageMatrixValues[4] / 2); //Y轴方向的位移
        matrix.postTranslate(transX, transY);
        setImageMatrix(matrix);
        invalidate();
    }

    /**
     * 计算边界缩放比例 isMinScale 是否最小比例，true 最小缩放比例， false 最大缩放比例
     */
    private float getScale(int bitmapWidth, int bitmapHeight, float minWidth, float minHeight, boolean isMinScale) {
        float scale;
        float scaleX = minWidth / bitmapWidth;
        float scaleY = minHeight / bitmapHeight;
        if (isMinScale) {
            scale = Math.max(scaleX, scaleY);
        } else {
            scale = Math.min(scaleX, scaleY);
        }
        return scale;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
//         高度为缩放高度
        if (topBitmap != null) {
            float wSca = NumberUtil.divide(measureWidth, topBitmap.getWidth());
            Log.w(TAG, "计算出来 :" + wSca);
            int topBimHeight = topBitmap.getHeight();
            height = (int) (topBimHeight * wSca);
            Log.w(TAG, "计算出来宽:" + measureWidth + "高：" + height);
            setMeasuredDimension(measureWidth, height);
            initImage();
        }
    }


    /**
     * 绘制焦点框
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw");
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // 给背景扣个洞
            int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), mCropPath);
            canvas.drawColor(cropMidColor);
            mCropPath.setXfermode(xModeSrc);
            canvas.drawBitmap(topBitmap, bgRect, bgRectF, mCropPath);
            mCropPath.setXfermode(null);
            canvas.restoreToCount(sc);
        } else {
            canvas.drawBitmap(topBitmap, bgRect, bgRectF, mCropPath);
        }

        Log.d(TAG, "用户信息：" + messageObj);
        if (messageObj != null) {
            float heightMax = (bgRectF.bottom - bgRectF.top);
            float lMar = 0.40F * (bgRectF.right - bgRectF.left) + bgRectF.left;
            float rMar = 0.88F * (bgRectF.right - bgRectF.left) + bgRectF.left;
            float hMid = (bgRectF.bottom - bgRectF.top) * 0.5f + bgRectF.top;

            // 小编号
            textPaint.setTypeface(Typeface.DEFAULT);
            textPaint.setColor(Color.parseColor("#6F6F6F"));
            textPaint.setTextSize(30);
            textPaint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText(messageObj.getIssue(), rMar, hMid + 0.01F * heightMax, textPaint);

            // 金额
            Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC);
            textPaint.setTypeface(font);
            textPaint.setColor(Color.parseColor("#00783C"));
            textPaint.setTextSize(120);
            textPaint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText(messageObj.getAmount(), rMar - 30, hMid + 0.13F * heightMax, textPaint);

            // 画货币符号
            float tvWidth = textPaint.measureText(messageObj.getAmount());
            textPaint.setTypeface(font);
            textPaint.setTextSize(60);
            textPaint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText(messageObj.getCurrencySymbol(), rMar - 30 - tvWidth, hMid + 0.08F * heightMax, textPaint);

            // 奖励金
            font = Typeface.create(Typeface.SANS_SERIF, Typeface.ITALIC);
            textPaint.setTypeface(font);
            textPaint.setTextSize(60);
            textPaint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText(messageObj.getCreditDes(), rMar - 30, hMid + 0.19F * heightMax, textPaint);


            // 画框
            float diff = 0.05F * heightMax;
            float topScale = 0.23F;
            topRoundRect.set(lMar, hMid + topScale * heightMax, rMar, hMid + topScale * heightMax + diff);
            canvas.drawRoundRect(topRoundRect, diff * 0.5F, diff * 0.5F, tBgPaint);


            // 下面框
            topScale = 0.30F;
            bottomRoundRect.set(lMar, hMid + topScale * heightMax, rMar, hMid + topScale * heightMax + diff);
            canvas.drawRoundRect(bottomRoundRect, diff * 0.5F, diff * 0.5F, tBgPaint);

            // 第一个框文字
            float baseLine = (topRoundRect.bottom - topRoundRect.top) * 0.75F + topRoundRect.top;
            textPaint.setTypeface(Typeface.DEFAULT);
            textPaint.setTextSize(40);
            textPaint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(messageObj.getName(), topRoundRect.centerX(), baseLine, textPaint);

            // 如果国旗存在
            if (flagBim != null) {
                int flagWidth = flagBim.getWidth();
                int flagHeight = flagBim.getHeight();
                float imgSpace = 30F;
                float imgTop = (bottomRoundRect.bottom - bottomRoundRect.top) * 0.15F + bottomRoundRect.top;
                float imgH = (bottomRoundRect.bottom - bottomRoundRect.top) * 0.7F;
                float imgW = (imgH / flagHeight) * flagWidth;
                flagRectSrc.set(0, 0, flagWidth, flagHeight);
                flagRectF.set(bottomRoundRect.centerX() - imgW - imgSpace, imgTop, bottomRoundRect.centerX() - imgSpace, imgTop + imgH);
                Log.i(TAG, "图片：" + flagRectSrc);
                Log.w(TAG, "图片：" + flagRectF);
                canvas.drawBitmap(flagBim, flagRectSrc, flagRectF, flagPaint);

                // 第二个框文字
                baseLine = (bottomRoundRect.bottom - bottomRoundRect.top) * 0.75F + bottomRoundRect.top;
                bottomRoundRect.left = lMar + imgSpace * 2F;
                textPaint.setTypeface(Typeface.DEFAULT);
                textPaint.setTextSize(40);
                textPaint.setTextAlign(Paint.Align.CENTER);
                canvas.drawText(messageObj.getCountryName(), bottomRoundRect.centerX(), baseLine, textPaint);

            } else {
                // 第二个框文字
                baseLine = (bottomRoundRect.bottom - bottomRoundRect.top) * 0.75F + bottomRoundRect.top;
                textPaint.setTypeface(Typeface.DEFAULT);
                textPaint.setTextSize(40);
                textPaint.setTextAlign(Paint.Align.CENTER);
                canvas.drawText(messageObj.getCountryName(), bottomRoundRect.centerX(), baseLine, textPaint);
            }

        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mSaving || null == getDrawable()) {
            return super.onTouchEvent(event);
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:  //第一个点按下
                savedMatrix.set(matrix);   //以后每次需要变换的时候，以现在的状态为基础进行变换
                pA.set(event.getX(), event.getY());
                pB.set(event.getX(), event.getY());
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:  //第二个点按下
                if (event.getActionIndex() > 1) break;
                pA.set(event.getX(0), event.getY(0));
                pB.set(event.getX(1), event.getY(1));
                midPoint.set((pA.x + pB.x) / 2, (pA.y + pB.y) / 2);
                oldDist = spacing(pA, pB);
                savedMatrix.set(matrix);  //以后每次需要变换的时候，以现在的状态为基础进行变换
                if (oldDist > 10f) mode = ZOOM_OR_ROTATE;//两点之间的距离大于10才有效
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == ZOOM_OR_ROTATE) {
                    PointF pC = new PointF(event.getX(1) - event.getX(0) + pA.x, event.getY(1) - event.getY(0) + pA.y);
                    double a = spacing(pB.x, pB.y, pC.x, pC.y);
                    double b = spacing(pA.x, pA.y, pC.x, pC.y);
                    double c = spacing(pA.x, pA.y, pB.x, pB.y);
                    if (a >= 10) {
                        double cosB = (a * a + c * c - b * b) / (2 * a * c);
                        double angleB = Math.acos(cosB);
                        double PID4 = Math.PI / 4;
                        //旋转时，默认角度在 45 - 135 度之间
                        if (angleB > PID4 && angleB < 3 * PID4) mode = ROTATE;
                        else mode = ZOOM;
                    }
                }
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - pA.x, event.getY() - pA.y);
                    fixTranslation();
                    setImageMatrix(matrix);
                } else if (mode == ZOOM) {
                    float newDist = spacing(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        // 这里之所以用 maxPostScale 矫正一下，主要是防止缩放到最大时，继续缩放图片会产生位移
                        float tScale = Math.min(newDist / oldDist, maxPostScale());
                        if (tScale != 0) {
                            matrix.postScale(tScale, tScale, midPoint.x, midPoint.y);
                            fixScale();
                            fixTranslation();
                            setImageMatrix(matrix);
                        }
                    }
                } else if (mode == ROTATE) {
                    PointF pC = new PointF(event.getX(1) - event.getX(0) + pA.x, event.getY(1) - event.getY(0) + pA.y);
                    double a = spacing(pB.x, pB.y, pC.x, pC.y);
                    double b = spacing(pA.x, pA.y, pC.x, pC.y);
                    double c = spacing(pA.x, pA.y, pB.x, pB.y);
                    if (b > 10) {
                        double cosA = (b * b + c * c - a * a) / (2 * b * c);
                        double angleA = Math.acos(cosA);
                        double ta = pB.y - pA.y;
                        double tb = pA.x - pB.x;
                        double tc = pB.x * pA.y - pA.x * pB.y;
                        double td = ta * pC.x + tb * pC.y + tc;
                        if (td > 0) {
                            angleA = 2 * Math.PI - angleA;
                        }
                        rotation = angleA;
                        matrix.set(savedMatrix);
                        matrix.postRotate((float) (rotation * 180 / Math.PI), midPoint.x, midPoint.y);
                        setImageMatrix(matrix);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                if (mode == DRAG) {
                    if (spacing(pA, pB) < 50) {
                        // 两次点击距离比较小
                    }
                } else if (mode == ROTATE) {
                    int rotateLevel = (int) Math.floor((rotation + Math.PI / 4) / (Math.PI / 2));
                    if (rotateLevel == 4) rotateLevel = 0;
                    matrix.set(savedMatrix);
                    matrix.postRotate(90 * rotateLevel, midPoint.x, midPoint.y);
                    if (rotateLevel == 1 || rotateLevel == 3) {
                        int tmp = mRotatedImageWidth;
                        mRotatedImageWidth = mRotatedImageHeight;
                        mRotatedImageHeight = tmp;
                    }
                    fixScale();
                    fixTranslation();
                    setImageMatrix(matrix);
                }
                mode = NONE;
                break;

            default:
                break;
        }
        //解决部分机型无法拖动的问题
        ViewCompat.postInvalidateOnAnimation(this);
        return true;
    }

    /**
     * 修正图片的缩放比
     */
    private void fixScale() {
        float imageMatrixValues[] = new float[9];
        matrix.getValues(imageMatrixValues);
        float currentScale = Math.abs(imageMatrixValues[0]) + Math.abs(imageMatrixValues[1]);
        float minScale = getScale(mRotatedImageWidth, mRotatedImageHeight, mFocusWidth, mFocusHeight, true);
        mMaxScale = minScale * MAX_SCALE;

        //保证图片最小是占满中间的焦点空间
        if (currentScale < minScale) {
            float scale = minScale / currentScale;
            matrix.postScale(scale, scale);
        } else if (currentScale > mMaxScale) {
            float scale = mMaxScale / currentScale;
            matrix.postScale(scale, scale);
        }
    }

    /**
     * 修正图片的位移
     */
    private void fixTranslation() {
        RectF imageRect = new RectF(0, 0, mImageWidth, mImageHeight);
        matrix.mapRect(imageRect);  //获取当前图片（缩放以后的）相对于当前控件的位置区域，超过控件的上边缘或左边缘为负
        float deltaX = 0, deltaY = 0;
        Log.w(TAG, "缩放：" + imageRect + "\n 控制：" + bgRectF);
        if (imageRect.left > mFocusRect.left) {
            deltaX = -imageRect.left + mFocusRect.left;
        } else if (imageRect.right < mFocusRect.right) {
            deltaX = -imageRect.right + mFocusRect.right;
        }
        if (imageRect.top > mFocusRect.top) {
            deltaY = -imageRect.top + mFocusRect.top;
        } else if (imageRect.bottom < mFocusRect.bottom) {
            deltaY = -imageRect.bottom + mFocusRect.bottom;
        }
        Log.e(TAG, "移动多少：" + deltaX + " - " + deltaY);
        matrix.postTranslate(deltaX, deltaY);
    }


    /**
     * 获取当前图片允许的最大缩放比
     */
    private float maxPostScale() {
        float imageMatrixValues[] = new float[9];
        matrix.getValues(imageMatrixValues);
        float curScale = Math.abs(imageMatrixValues[0]) + Math.abs(imageMatrixValues[1]);
        return mMaxScale / curScale;
    }

    /**
     * 计算两点之间的距离
     */
    private float spacing(float x1, float y1, float x2, float y2) {
        float x = x1 - x2;
        float y = y1 - y2;
        return (float) Math.sqrt(x * x + y * y);
    }

    /**
     * 计算两点之间的距离
     */
    private float spacing(PointF pA, PointF pB) {
        return spacing(pA.x, pA.y, pB.x, pB.y);
    }

    /**
     * @param expectWidth  期望的宽度
     * @param exceptHeight 期望的高度
     * @return 裁剪后的Bitmap
     */
    public Bitmap getCropBitmap(int expectWidth, int exceptHeight) {
        if (expectWidth <= 0 || exceptHeight < 0) return null;
        Bitmap srcBitmap = convertViewToBitmap(this);
        if (srcBitmap == null) return null;
        return makeCropBitmap(srcBitmap, bgRectF, expectWidth, exceptHeight);
    }

    /**
     * 把当前视图整个转成bitmap
     */
    public Bitmap convertViewToBitmap(View view) {
        Log.d(TAG, "convertViewToBitmap ww:" + view.getWidth() + " hh:" + view.getHeight());
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        //利用bitmap生成画布
        Canvas canvas = new Canvas(bitmap);
        //把view中的内容绘制在画布上
        view.draw(canvas);
        return bitmap;
    }

    /**
     * @param bitmap       需要裁剪的图片
     * @param focusRect    中间需要裁剪的矩形区域
     * @param expectWidth  希望获得的图片宽度，如果图片宽度不足时，拉伸图片
     * @param exceptHeight 希望获得的图片高度，如果图片高度不足时，拉伸图片
     * @return 裁剪后的图片的Bitmap
     */
    private Bitmap makeCropBitmap(Bitmap bitmap, RectF focusRect, int expectWidth, int exceptHeight) {
        int left = (int) focusRect.left;
        int top = (int) focusRect.top;
        int width = (int) focusRect.width();
        int height = (int) focusRect.height();
        if (left < 0) left = 0;
        if (top < 0) top = 0;
        if (left + width > bitmap.getWidth()) width = bitmap.getWidth() - left;
        if (top + height > bitmap.getHeight()) height = bitmap.getHeight() - top;
        try {
            bitmap = Bitmap.createBitmap(bitmap, left, top, width, height);
            if (expectWidth != width || exceptHeight != height) {
                bitmap = Bitmap.createScaledBitmap(bitmap, expectWidth, exceptHeight, true);
            }
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * @param folder       希望保存的文件夹
     * @param expectWidth  希望保存的图片宽度
     * @param exceptHeight 希望保存的图片高度
     */
    public boolean saveBitmapToFile(File folder, int expectWidth, int exceptHeight) {
        if (mSaving) return false;
        final Bitmap croppedImage = getCropBitmap(expectWidth, exceptHeight);
        if (croppedImage == null) {
            return false;
        }
        String savePath = folder.getAbsolutePath() + File.separator + "IMG_" + System.currentTimeMillis() + "_cacheImage.jpg";
        new Thread() {
            @Override
            public void run() {
//                boolean save = ImageUtilZ.save(croppedImage, savePath, Bitmap.CompressFormat.JPEG);
//                File saveFile = new File(savePath);
//                if (save) {
//                    Message.obtain(mHandler, SAVE_SUCCESS, saveFile).sendToTarget();
//                } else {
//                    Message.obtain(mHandler, SAVE_ERROR, saveFile).sendToTarget();
//                }
            }
        }.start();
        return true;
    }

    private static class InnerHandler extends Handler {
        private SoftReference<OnBitmapSaveCompleteListener> mListener;

        public InnerHandler() {
            super(Looper.getMainLooper());
        }

        public void setListener(OnBitmapSaveCompleteListener listener) {
            this.mListener = new SoftReference<OnBitmapSaveCompleteListener>(listener);
        }

        @Override
        public void handleMessage(Message msg) {
            File saveFile = (File) msg.obj;
            switch (msg.what) {
                case SAVE_SUCCESS:
                    if (mListener.get() != null) mListener.get().onBitmapSaveSuccess(saveFile);
                    break;
                case SAVE_ERROR:
                    if (mListener.get() != null) mListener.get().onBitmapSaveError(saveFile);
                    break;

                default:
                    break;
            }
        }
    }

    /**
     * 图片保存完成的监听
     */
    private OnBitmapSaveCompleteListener mListener;

    public interface OnBitmapSaveCompleteListener {
        void onBitmapSaveSuccess(File file);

        void onBitmapSaveError(File file);
    }

    public void setBitmapSaveCompleteListener(OnBitmapSaveCompleteListener listener) {
        mListener = listener;
        mHandler.setListener(listener);
    }

}